/*
    SqliteHelper类：封装SQLite数据库的基本操作，提供简单的数据库管理接口。
    功能包括：
        1. 创建/打开数据库文件
        2. 执行SQL语句（支持回调函数处理查询结果）
        3. 关闭数据库连接
*/
#include <iostream>
#include <string>
#include <vector>
#include <sqlite3.h>


class SqliteHelper 
{
    public:
        // SQLite回调函数类型定义，用于处理sqlite3_exec的查询结果
        // 参数说明：
        // void* arg - 用户自定义参数
        // int col_num - 结果列数
        // char** col_values - 每列的值数组
        // char** col_names - 每列的字段名数组
        typedef int(*SqliteCallback)(void*,int,char**,char**);
        
        // 构造函数
        // 参数说明：
        // dbfile - 数据库文件路径（如: "test.db"）
        SqliteHelper(const std::string &dbfile) : _dbfile(dbfile), _handler(nullptr){}
        
        // 打开/创建数据库
        // 参数说明：
        // safe_leve - 线程安全级别（默认SQLITE_OPEN_FULLMUTEX，表示线程安全模式）
        // 返回值：bool - 成功返回true，失败输出错误信息并返回false
        bool open(int safe_leve = SQLITE_OPEN_FULLMUTEX) 
        {
            // SQLITE_OPEN_READWRITE：可读写模式
            // SQLITE_OPEN_CREATE：如果数据库不存在则创建
            // safe_leve：控制并发访问的线程安全级别
            int ret = sqlite3_open_v2(
                _dbfile.c_str(), 
                &_handler, 
                SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | safe_leve, 
                nullptr
            );
            
            if (ret != SQLITE_OK) 
            {
                std::cout << "创建/打开sqlite数据库失败: ";
                std::cout << sqlite3_errmsg(_handler) << std::endl;
                return false;
            }
            return true;
        }
        
        // 执行SQL语句
        // 参数说明：
        // sql - 要执行的SQL语句
        // cb - 回调函数指针（查询语句时处理结果集，增删改操作可传nullptr）
        // arg - 传递给回调函数的用户自定义参数
        // 返回值：bool - 成功返回true，失败输出错误信息并返回false
        bool exec(const std::string &sql, SqliteCallback cb, void *arg) 
        {
            int ret = sqlite3_exec(
                _handler, 
                sql.c_str(), 
                cb,    // 每查到一条记录调用一次回调函数
                arg,   // 回调函数的第一个参数
                nullptr // 错误信息存储位置（nullptr表示不捕获）
            );
            
            if (ret != SQLITE_OK) 
            {
                std::cout << "执行失败语句: " << sql << std::endl;
                std::cout << "错误信息: " << sqlite3_errmsg(_handler) << std::endl;
                return false;
            }
            return true;
        }
        
        // 关闭数据库连接
        // 注意：确保所有操作完成后调用，释放数据库资源
        void close() {
            if (_handler) 
            {
                // 使用v2版本允许在关闭后重置指针
                sqlite3_close_v2(_handler);
                _handler = nullptr;  // 防止野指针
            }
        }
        
    private:
        std::string _dbfile;   // 数据库文件路径
        sqlite3* _handler;     // SQLite数据库句柄指针
};